package com.zenithmind.common.health;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;

/**
 * 自定义健康检查指标
 * 检查应用的内存使用情况和其他关键指标
 */
@Slf4j
@Component
public class CustomHealthIndicator implements HealthIndicator {
    
    private static final double MEMORY_THRESHOLD = 0.85; // 内存使用率阈值85%
    
    @Override
    public Health health() {
        try {
            // 检查内存使用情况
            MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
            MemoryUsage heapMemoryUsage = memoryBean.getHeapMemoryUsage();
            
            long used = heapMemoryUsage.getUsed();
            long max = heapMemoryUsage.getMax();
            double memoryUsageRatio = (double) used / max;
            
            Health.Builder healthBuilder = Health.up();
            
            // 添加内存信息
            healthBuilder
                .withDetail("memory.used", formatBytes(used))
                .withDetail("memory.max", formatBytes(max))
                .withDetail("memory.usage_ratio", String.format("%.2f%%", memoryUsageRatio * 100))
                .withDetail("memory.available", formatBytes(max - used));
            
            // 检查内存使用率
            if (memoryUsageRatio > MEMORY_THRESHOLD) {
                healthBuilder.down()
                    .withDetail("memory.status", "HIGH_USAGE")
                    .withDetail("memory.warning", "内存使用率超过阈值: " + (MEMORY_THRESHOLD * 100) + "%");
            } else {
                healthBuilder.withDetail("memory.status", "NORMAL");
            }
            
            // 添加JVM信息
            Runtime runtime = Runtime.getRuntime();
            healthBuilder
                .withDetail("jvm.processors", runtime.availableProcessors())
                .withDetail("jvm.version", System.getProperty("java.version"))
                .withDetail("jvm.vendor", System.getProperty("java.vendor"));
            
            // 添加应用启动时间
            long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
            healthBuilder.withDetail("uptime", formatDuration(uptime));
            
            return healthBuilder.build();
            
        } catch (Exception e) {
            log.error("健康检查失败", e);
            return Health.down()
                .withDetail("error", e.getMessage())
                .withDetail("status", "HEALTH_CHECK_FAILED")
                .build();
        }
    }
    
    /**
     * 格式化字节数
     */
    private String formatBytes(long bytes) {
        if (bytes < 1024) {
            return bytes + " B";
        } else if (bytes < 1024 * 1024) {
            return String.format("%.2f KB", bytes / 1024.0);
        } else if (bytes < 1024 * 1024 * 1024) {
            return String.format("%.2f MB", bytes / (1024.0 * 1024.0));
        } else {
            return String.format("%.2f GB", bytes / (1024.0 * 1024.0 * 1024.0));
        }
    }
    
    /**
     * 格式化持续时间
     */
    private String formatDuration(long milliseconds) {
        long seconds = milliseconds / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        long days = hours / 24;
        
        if (days > 0) {
            return String.format("%d天 %d小时 %d分钟", days, hours % 24, minutes % 60);
        } else if (hours > 0) {
            return String.format("%d小时 %d分钟", hours, minutes % 60);
        } else if (minutes > 0) {
            return String.format("%d分钟 %d秒", minutes, seconds % 60);
        } else {
            return String.format("%d秒", seconds);
        }
    }
}
